#include "protocol/JsonRpcHandlerImpl.h"
#include "protocol/JsonRpcMessageParser.h"
#include "protocol/JsonRpcMessageSerializer.h"
#include "message_serialization/JsonRpcErrorCode.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDebug>
#include <memory>

JsonRpcHandlerImpl::JsonRpcHandlerImpl()
    : IProtocolHandler()
    , mMessageParser(nullptr)
    , mMessageSerializer(nullptr)
{
}

JsonRpcHandlerImpl::~JsonRpcHandlerImpl()
{
}

void JsonRpcHandlerImpl::setMessageParser(std::unique_ptr<IMessageParser> parser)
{
    if (parser) {
        mMessageParser = std::move(parser);
    }
}

void JsonRpcHandlerImpl::setMessageSerializer(std::unique_ptr<IMessageSerializer> serializer)
{
    if (serializer) {
        mMessageSerializer = std::move(serializer);
    }
}

QJsonObject JsonRpcHandlerImpl::parseRequest(const QByteArray& data)
{
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        return createErrorResponse(RpcError::PARSE_ERROR,
                                   QString::fromStdString(RpcError::Code2Msg(RpcError::PARSE_ERROR)));
    }

    if (doc.isObject()) {
        QJsonObject request = doc.object();

        // Validation is done in processSingleRequest to avoid duplicate validation
        return processSingleRequest(request);
    }
    else {
        return createErrorResponse(-32600, "Invalid JSON-RPC message");
    }
}

QByteArray JsonRpcHandlerImpl::serializeResponse(const QJsonObject& response)
{
    return mMessageSerializer->toByteArray(response);
}

QJsonObject JsonRpcHandlerImpl::createErrorResponse(int code, const QJsonValue& message)
{
    return mMessageSerializer->serializeErrorResponse(QJsonValue(), code, message);
}

QJsonObject JsonRpcHandlerImpl::processSingleRequest(const QJsonObject& request)
{
    // Validate the request structure
    if (!mMessageParser->validateMessage(request)) {
        return createErrorResponse(-32600, "Invalid Request");
    }

    if (mMessageParser->isNotification(request)) {
        // For notifications, we don't send a response
        return QJsonObject();
    }

    // Extract request ID for response
    QJsonValue id = request.value("id");

    // Extract method name
    QString method = mMessageParser->parseMethodName(request);
    if (method.isEmpty()) {
        return mMessageSerializer->serializeErrorResponse(id, -32601, "Method not found");
    }

    // Extract parameters
    QJsonObject params = mMessageParser->parseParameters(request);

    /// @todo: Implement actual method dispatch logic here
    // For now, return a simple success response
    QJsonObject result;
    result["status"] = "success";
    result["method"] = method;

    return mMessageSerializer->serializeSuccessResponse(id, result);
}
